package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.DigitalCollectionDao;
import com.sc.nft.dao.UserEcologyHatchCollectionRecordsDao;
import com.sc.nft.dto.EcologyCollectionNodeConfDao;
import com.sc.nft.dto.EcologyHatchIncomeConfDao;
import com.sc.nft.dto.EcologyHatchIncomeConfRelevanceDao;
import com.sc.nft.entity.DigitalCollection;
import com.sc.nft.entity.EcologyCollectionNodeConf;
import com.sc.nft.entity.EcologyHatchIncomeConf;
import com.sc.nft.entity.EcologyHatchIncomeConfRelevance;
import com.sc.nft.entity.dto.AdminEcologyIncomeDTO;
import com.sc.nft.entity.req.AdminEcologyIncomeConfCollectionReq;
import com.sc.nft.entity.req.AdminEcologyIncomeConfReq;
import com.sc.nft.entity.vo.ecology.*;
import com.sc.nft.enums.DigitalMarketTypeEnum;
import com.sc.nft.enums.ReceivedCollectionType;
import com.sc.nft.enums.UserEcologyHatchCollectionTypeRecordsEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.AdminEcologyNodeConfService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class AdminEcologyNodeConfServiceImpl implements AdminEcologyNodeConfService {

    private final EcologyHatchIncomeConfDao ecologyHatchIncomeConfDao;
    private final EcologyCollectionNodeConfDao ecologyCollectionNodeConfDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final UserEcologyHatchCollectionRecordsDao userEcologyHatchCollectionRecordsDao;
    private final EcologyHatchIncomeConfRelevanceDao ecologyHatchIncomeConfRelevanceDao;

    @Override
    public AdminEcologyIncomeConfRelevanceVO getAdminIncomeConf(Long id) {
        AdminEcologyIncomeConfRelevanceVO adminEcologyIncomeConfRelevanceVO = new AdminEcologyIncomeConfRelevanceVO();
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        List<AdminEcologyIncomeConfVO> incomeList = BeanUtil.copyToList(ecologyHatchIncomeConfDao.getAdminIncomeConfByRelevanceId(id), AdminEcologyIncomeConfVO.class);
        for (AdminEcologyIncomeConfVO adminEcologyIncomeConfVO : incomeList) {
            adminEcologyIncomeConfVO.setStanding(adminEcologyIncomeConfVO.getIncomeType().getStanding());
        }
        adminEcologyIncomeConfRelevanceVO.setId(confRelevance.getId());
        adminEcologyIncomeConfRelevanceVO.setHatchCollectionId(confRelevance.getHatchCollectionId());
        adminEcologyIncomeConfRelevanceVO.setHatchCollectionName(confRelevance.getHatchCollectionName());
        adminEcologyIncomeConfRelevanceVO.setList(incomeList);
        return adminEcologyIncomeConfRelevanceVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchUpateIncomeScale(List<AdminEcologyIncomeDTO> list,Long id,Long hatchCollectionId) {
        EcologyHatchIncomeConfRelevance relevanceDaoById = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.isFalse(relevanceDaoById.getIsOpen(),()->new GlobalRunTimeException("请关闭配置再进行修改"));
        int count = ecologyHatchIncomeConfRelevanceDao.checkHatchCollectionBind(id,hatchCollectionId);
        Assert.isTrue(count <= 0,()->new GlobalRunTimeException("该熔炼藏品已绑定"));
        DigitalCollection hatchCollection = digitalCollectionDao.getById(hatchCollectionId);
        Assert.notNull(hatchCollection,()->new GlobalRunTimeException("绑定熔炼藏品不存在"));
        BigDecimal sumTotal = list.stream().map(AdminEcologyIncomeDTO::getIncomeScale).reduce(BigDecimal.ZERO, BigDecimal::add);
        Assert.isTrue(sumTotal.compareTo(new BigDecimal(100)) <= 0, () -> new GlobalRunTimeException("总占比不能大于100%"));
        for (AdminEcologyIncomeDTO adminEcologyIncomeDTO : list) {
            Assert.isTrue(ecologyHatchIncomeConfDao.updateIncomeScaleById(adminEcologyIncomeDTO.getId(), adminEcologyIncomeDTO.getIncomeScale()),()->new GlobalRunTimeException("修改失败"));
        }
        Assert.isTrue(ecologyHatchIncomeConfRelevanceDao.updateTotalIncomeScaleAndHatchCollectionId(id,hatchCollectionId,hatchCollection.getFirstTitle(),sumTotal),()->new GlobalRunTimeException("修改失败"));
    }

    @Override
    public List<AdminNodeCollectionVO> getNodeCollectionList(Long id) {
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        return BeanUtil.copyToList(ecologyCollectionNodeConfDao.listByRelevanceId(id),AdminNodeCollectionVO.class);
    }

    @Override
    public void addNodeCollection(Long collectionId,Long id) {
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        Assert.isFalse(confRelevance.getIsOpen(),()->new GlobalRunTimeException("请关闭配置再进行修改"));
        DigitalCollection collection = digitalCollectionDao.getById(collectionId);
        Assert.notNull(collection,()->new GlobalRunTimeException("藏品不存在"));
        //上线前修改 所有藏品都可以配置(除了版权藏品都可以配置)
        Assert.isTrue(collection.getCollectionType() != DigitalMarketTypeEnum.COPYRIGHT,()->new GlobalRunTimeException("版权藏品不能配置成为生态节点"));

        Integer count = ecologyCollectionNodeConfDao.getCountByCollectionIdAndRelevanceId(collectionId,id);
        Assert.isTrue(count == 0,()->new GlobalRunTimeException("该藏品已经添加"));

        EcologyCollectionNodeConf ecologyCollectionNodeConf = new EcologyCollectionNodeConf();
        ecologyCollectionNodeConf.setCollectionId(collectionId);
        ecologyCollectionNodeConf.setConfRelevanceId(id);
        ecologyCollectionNodeConf.setCollectionName(collection.getFirstTitle());
        ecologyCollectionNodeConf.insert();
    }

    @Override
    public void delNodeCollection(Long collectionId,Long id) {
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        Assert.isFalse(confRelevance.getIsOpen(),()->new GlobalRunTimeException("请关闭配置再进行修改"));
        EcologyCollectionNodeConf ecologyCollectionNodeConf = ecologyCollectionNodeConfDao.getOneByCollectionIdAndRelevanceId(collectionId,id);
        Assert.notNull(ecologyCollectionNodeConf,()->new GlobalRunTimeException("节点藏品不存在"));
        Assert.isTrue(ecologyCollectionNodeConfDao.removeById(ecologyCollectionNodeConf.getId()),()->new GlobalRunTimeException("删除失败"));
    }

    @Override
    public Page<AdminEcologyRecycleRecordsVO> ecologyRecycleRecords(String collectionName, String numbering, String userTel, ReceivedCollectionType type, String beginTime, String endTime, Page page, UserEcologyHatchCollectionTypeRecordsEnum collectionStatus) {
        return userEcologyHatchCollectionRecordsDao.ecologyRecycleRecords(page,collectionName,numbering,userTel, ObjectUtil.isNull(type) ? null :type.getCode(),beginTime,endTime,ObjectUtil.isNull(collectionStatus)?null:collectionStatus.getCode());
    }

    /**
     * 平台权益配置列表
     *
     * @param pageNo
     * @param pageSize
     * @param hatchCollectionId
     * @param isOpen
     * @return
     */
    @Override
    public IPage<AdminEcologyIncomeConfPageVO> adminIncomeConfPage(Integer pageNo, Integer pageSize, Long hatchCollectionId, Boolean isOpen) {
        return ecologyHatchIncomeConfRelevanceDao.adminIncomeConfPage(pageNo,pageSize,hatchCollectionId,isOpen);
    }

    /**
     * 添加配置
     *
     * @param list
     * @param hatchCollectionId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addIncomeScale(List<AdminEcologyIncomeConfReq> list, Long hatchCollectionId,List<AdminEcologyIncomeConfCollectionReq> collectionIdList) {
        int count = ecologyHatchIncomeConfRelevanceDao.checkHatchCollectionBind(null,hatchCollectionId);
        Assert.isTrue(count <= 0,()->new GlobalRunTimeException("该熔炼藏品已绑定"));
        DigitalCollection hatchCollection = digitalCollectionDao.getById(hatchCollectionId);
        Assert.notNull(hatchCollection,()->new GlobalRunTimeException("绑定熔炼藏品不存在"));
        BigDecimal sumTotal = list.stream().map(AdminEcologyIncomeConfReq::getIncomeScale).reduce(BigDecimal.ZERO, BigDecimal::add);
        Assert.isTrue(sumTotal.compareTo(new BigDecimal(100)) <= 0, () -> new GlobalRunTimeException("总占比不能大于100%"));
        EcologyHatchIncomeConfRelevance confRelevance = new EcologyHatchIncomeConfRelevance();
        confRelevance.setTotalIncomeScale(sumTotal);
        confRelevance.setIsOpen(Boolean.FALSE);
        confRelevance.setHatchCollectionId(hatchCollection.getId());
        confRelevance.setHatchCollectionName(hatchCollection.getFirstTitle());
        ecologyHatchIncomeConfRelevanceDao.save(confRelevance);
        List<EcologyHatchIncomeConf> ecologyHatchIncomeConfs = new ArrayList<>();
        for (AdminEcologyIncomeConfReq AdminEcologyIncomeConfReq : list) {
            EcologyHatchIncomeConf ecologyHatchIncomeConf = new EcologyHatchIncomeConf();
            ecologyHatchIncomeConf.setIncomeScale(AdminEcologyIncomeConfReq.getIncomeScale());
            ecologyHatchIncomeConf.setIncomeType(AdminEcologyIncomeConfReq.getIncomeType());
            ecologyHatchIncomeConf.setIncomeTypeName(AdminEcologyIncomeConfReq.getIncomeType().getDescription());
            ecologyHatchIncomeConf.setConfRelevanceId(confRelevance.getId());
            ecologyHatchIncomeConfs.add(ecologyHatchIncomeConf);
        }
        ecologyHatchIncomeConfDao.saveBatch(ecologyHatchIncomeConfs);

        if (!CollectionUtils.isEmpty(collectionIdList)) {
            List<EcologyCollectionNodeConf> nodeConfs = new ArrayList<>();
            for (AdminEcologyIncomeConfCollectionReq req : collectionIdList) {
                EcologyCollectionNodeConf ecologyCollectionNodeConf = new EcologyCollectionNodeConf();
                ecologyCollectionNodeConf.setCollectionId(req.getCollectionId());
                ecologyCollectionNodeConf.setCollectionName(req.getCollectionName());
                ecologyCollectionNodeConf.setConfRelevanceId(confRelevance.getId());
                nodeConfs.add(ecologyCollectionNodeConf);
            }
            ecologyCollectionNodeConfDao.saveBatch(nodeConfs);
        }
    }

    /**
     * @param id
     * @param isOpen
     */
    @Override
    public void button(Long id, Boolean isOpen) {
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        Assert.isFalse(confRelevance.getIsOpen() == isOpen,()->new GlobalRunTimeException("该状态无需修改"));
        Assert.isTrue(ecologyHatchIncomeConfRelevanceDao.updateIsOpen(id,isOpen),()->new GlobalRunTimeException("修改失败"));
    }

    /**
     * 删除
     *
     * @param id
     */
    @Override
    public void remove(Long id) {
        EcologyHatchIncomeConfRelevance confRelevance = ecologyHatchIncomeConfRelevanceDao.getById(id);
        Assert.notNull(confRelevance,()->new BeanException("配置不存在"));
        Assert.isFalse(confRelevance.getIsOpen(),()->new GlobalRunTimeException("该状态无法删除"));
        Assert.isTrue(ecologyHatchIncomeConfRelevanceDao.removeById(id),()->new GlobalRunTimeException("删除失败"));
        Assert.isTrue(ecologyCollectionNodeConfDao.removeByRelevanceId(id),()->new GlobalRunTimeException("删除失败"));
        Assert.isTrue(ecologyHatchIncomeConfDao.removeByRelevanceId(id),()->new GlobalRunTimeException("删除失败"));
    }
}
